// TODO clean namespace?
// remove debug console commands
var Graph;
var selectableObjects;
var overlayNewNode;
var fileName = "sample.json";

// gibts bessere Möglichkeiten die Kanten zu zeichnen?
var graphGraphic;

var drawEdges = function () {
  YUI().use('graphics', function(Y) {
	
    if (graphGraphic === undefined) {
      graphGraphic = new Y.Graphic({
        render: "#graphGraphic"
      });
    };
  
    graphGraphic.clear()
  
    // draw edges
    for (var key in Graph.nodes) {
      var node = Graph.nodes[key];
      var fromNode = Y.one('#node-' + node.id);
      for (var i in node._neighbors()) {
        var toNode = Y.one('#node-' + node._neighbors()[i]);
        console.log("from: " + fromNode + " _to: " + toNode);
				
        var edgeConnector = graphGraphic.addShape({
          type: "path",
          stroke: {
            weight: 2,
            color: "#000"
          },
          id: fromNode.get('id') + 'to' + toNode.get('id')
        });
		
        // TODO: computeCenter(yuinode) -> returns center of node (x, y)
        edgeConnector.moveTo(fromNode.getXY()[0] + 30, fromNode.getXY()[1] + 30);
        edgeConnector.lineTo(toNode.getXY()[0] + 30, toNode.getXY()[1] + 30);
        edgeConnector.end();
      };
    };
  })
};

// selectable objects handler (.node)
YUI().use("node", function(Y) {
  selectableObjects= function(e) {
    var node = e.currentTarget;
    var nodes = Y.all('.node');
    nodes.removeClass("selected");
    node.addClass("selected");
  };
  Y.on('click', selectableObjects, '.node');
});

YUI().use('json-parse','json-stringify','node', function (Y) {
  // import initial graph
  GraphApp.Test = {
    onLoad: function () {
      Graph = new GraphApp.Graph();
      Graph.graphImport(fileName);
    }
  };
  GraphApp.Test.onLoad();

  // add graph to draw area
  var graphPool = Y.one('#graphPool');
  
  
  // draw nodes
  for (var i = Graph.nodes.length - 1; i >= 0; --i) {
    var id = Graph.nodes[i].id;
    var value = Graph.nodes[i].value;
    var x = Graph.nodes[i].pos.x;
    var y = Graph.nodes[i].pos.y;
    graphPool.append('<div id= "node-' + id + '" style="left:'+ x +'px; top:'+ y +'px" class="node"><span>'+ value+'</span></div>')
  };
  
  drawEdges();
  
});



/**
 * Draggable Area
 */
YUI().use('dd','graphics', function(Y) {
  var dragable = new Y.DD.Drag({
    node: '.node'
  }).plug(Y.Plugin.DDConstrained, {
    constrain2node: '#graphPool'
  });

  var delegate = new Y.DD.Delegate({
    container: '#graphPool',
    nodes: 'div'
  });

  delegate.dd.plug(Y.Plugin.DDConstrained, {
    constrain2node: '#graphPool'
  });

  // Handle drag & drop of node
  // update node position in graph logic
  Y.DD.DDM.on('drag:drag', function(e) {
    var drag = e.target;
    var node = drag.get('node');
    // calculate offset (graph is not drawn at top of the window)
    var offset = Y.one('#graphPool').getXY();
    var x = Math.floor(e.target.lastXY[0] - offset[0]);
    var y = Math.floor(e.target.lastXY[1] - offset[1]);
    console.log(node.get('id').slice(5) + "   x:" + x + " _y:" + y);
	
    // update position in graph logic
    Graph.setCoordinates(node.get('id').slice(5), x, y);
	
    // update edges
    drawEdges();
  });
});


/**
 * Events
 */
YUI().use('node', function(Y) {
  Y.one('#addNodeForm').on('click', function(e) {
    Y.one('#addNodeFormToggle').show();
  });

  Y.one('#addNodeButton').on('click', function(e) {
    var graphPool = Y.one('#graphPool');
    var value = Y.one('#addNodeValue').get( "value" );
	
    // add node to graph
    var node = Graph.addNode(value, 0, 0);
	
    var elem = graphPool.append('<div id= "node-' + node.id + '" class="node"><span>'+value+'</span></div>');
    
    Y.on('click', selectableObjects, '.node');

    Y.one('#addNodeFormToggle').hide();
    Y.one('#addNodeValue').set("value","");
  });

  Y.one('#deleteNodeButton').on('click', function(e) {
    var graphPool = Y.one('#graphPool');
    var nodeToDelete = graphPool.one('.selected');
	
    // delete node from graph
    Graph.removeNode(nodeToDelete.get('id').slice(5));
	
    nodeToDelete.remove();
	
    drawEdges();
  });
});

